package multithreading;

import java.util.function.IntConsumer;

/**
 * @ClassName: ZeroEvenOdd
 * @Description 1116. 打印零与奇偶数
 * 相同的一个ZeroEvenOdd类实例将会传递给三个不同的线程：
 *
 * 线程 A 将调用zero()，它只输出 0 。
 * 线程 B 将调用even()，它只输出偶数。
 * 线程 C 将调用odd()，它只输出奇数。
 * 每个线程都有一个printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列010203040506... ，其中序列的长度必须为 2n。
 *
 * @Author skywingking
 * @Date 2021/11/17 4:19 下午
 **/
public class ZeroEvenOdd {
    private int n;

    private volatile int state;

    public ZeroEvenOdd(int n) {
        this.n = n;
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void zero(IntConsumer printNumber) throws InterruptedException {
        for(int i = 0; i < n; i++){
            while(state != 0){
                Thread.yield();
            }
            printNumber.accept(0);
            if(i % 2 == 0){
                state = 1;
            }else {
                state = 2;
            }
        }
    }

    public void even(IntConsumer printNumber) throws InterruptedException {
        for(int i = 2; i <= n; i+=2){
            while(state != 2){
                Thread.yield();
            }
            printNumber.accept(i);
            state = 0;
        }
    }

    public void odd(IntConsumer printNumber) throws InterruptedException {
        for (int i = 1; i <= n; i += 2) {
            while (state != 1) {
                Thread.yield();
            }
            printNumber.accept(i);
            state = 0;
        }
    }
}